package com.liujit.upms.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.lang.tree.Tree;
import cn.hutool.core.lang.tree.TreeNodeConfig;
import cn.hutool.core.lang.tree.TreeUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.enums.SqlKeyword;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.liujit.common.constants.ColumnConstant;
import com.liujit.common.constants.GlobalConstant;
import com.liujit.common.domain.params.BaseParams;
import com.liujit.common.domain.result.PageBean;
import com.liujit.common.exception.BusinessException;
import com.liujit.common.exception.DataNotFoundException;
import com.liujit.common.utils.DozerConvertor;
import com.liujit.common.utils.Pagination;
import com.liujit.upms.domain.model.SysMenu;
import com.liujit.upms.domain.model.SysPermission;
import com.liujit.upms.domain.model.SysRole;
import com.liujit.upms.domain.model.SysUserRole;
import com.liujit.upms.domain.params.SysRoleParams;
import com.liujit.upms.domain.params.SysRolePermParams;
import com.liujit.upms.domain.query.SysRoleQuery;
import com.liujit.upms.domain.result.SysRolePermResult;
import com.liujit.upms.domain.result.SysRoleResult;
import com.liujit.upms.mapper.SysRoleMapper;
import com.liujit.upms.service.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * @Description 系统角色Service实现类
 * @Author liujun
 * @Date 2021-07-02 15:01:11
 */
@Service
public class SysRoleServiceImpl extends ServiceImpl<SysRoleMapper, SysRole> implements SysRoleService {

    private SysUserRoleService sysUserRoleService;

    private SysMenuService sysMenuService;

    private SysPermissionService sysPermissionService;

    private SysOrgService sysOrgService;

    @Autowired
    public void setSysUserRoleService(SysUserRoleService sysUserRoleService) {
        this.sysUserRoleService = sysUserRoleService;
    }

    @Autowired
    public void setSysMenuService(SysMenuService sysMenuService) {
        this.sysMenuService = sysMenuService;
    }

    @Autowired
    public void setSysPermissionService(SysPermissionService sysPermissionService) {
        this.sysPermissionService = sysPermissionService;
    }

    @Autowired
    public void setSysOrgService(SysOrgService sysOrgService) {
        this.sysOrgService = sysOrgService;
    }

    @Override
    public PageBean<SysRoleResult> getPage(SysRoleQuery query) {
        // 排序
        if (StrUtil.isNotBlank(query.getSortName()) && StrUtil.isNotBlank(query.getSortOrder())) {
            query.setSortName(ColumnConstant.CREATE_TIME);
            query.setSortOrder(SqlKeyword.DESC.getSqlSegment());
        }
        Page<SysRole> page = Pagination.page(query);
        LambdaQueryWrapper<SysRole> wrapper = new LambdaQueryWrapper();
        wrapper.ne(SysRole::getId, GlobalConstant.SUPER_ROLE_ID);
        if (StrUtil.isNotEmpty(query.getName())) {
            wrapper.like(SysRole::getName, query.getName());
        }
        if (query.getOrgId() != null) {
            wrapper.eq(SysRole::getOrgId, query.getOrgId());
        }
        if (query.getEnabled() != null) {
            wrapper.eq(SysRole::getEnabled, query.getEnabled());
        }
        if (query.getStartTime() != null) {
            wrapper.ge(SysRole::getCreateTime, query.getStartTime());
        }
        if (query.getEndTime() != null) {
            wrapper.le(SysRole::getCreateTime, query.getEndTime());
        }
        IPage<SysRole> iPage = super.page(page, wrapper);
        return PageBean.page(iPage, SysRoleResult.class);
    }

    @Override
    public Boolean save(SysRoleParams params) {
        SysRole entity = DozerConvertor.convertor(params, SysRole.class);
        // 添加
        if (params.getId() == null) {
            entity.setEnabled(GlobalConstant.ENABLED_YES);
            return super.save(entity);
        } else {
            SysRole sysRole = super.getById(params.getId());
            if (sysRole == null) {
                throw new DataNotFoundException();
            }
            return super.updateById(entity);
        }
    }

    @Override
    public SysRoleResult get(Long id) {
        SysRole sysRole = super.getById(id);
        if (sysRole == null) {
            throw new DataNotFoundException();
        }
        return DozerConvertor.convertor(sysRole, SysRoleResult.class);
    }

    @Override
    public SysRoleResult getDetail(Long id) {
        SysRoleResult result = this.get(id);
        result.setOrgName(sysOrgService.getNameById(result.getOrgId()));
        List<Map<String, Object>> list = new ArrayList<>();
        // 查询角色菜单
        List<Long> menuIds = sysMenuService.getMenuIdByRoleId(id);
        if (CollectionUtil.isNotEmpty(menuIds)) {
            LambdaQueryWrapper<SysMenu> wrapper = new LambdaQueryWrapper<>();
            wrapper.select(SysMenu::getId, SysMenu::getPid, SysMenu::getName);
            wrapper.eq(SysMenu::getEnabled, GlobalConstant.ENABLED_YES);
            wrapper.in(SysMenu::getId, menuIds);
            List<Map<String, Object>> menus = sysMenuService.listMaps(wrapper);
            if (CollectionUtil.isNotEmpty(menus)) {
                list.addAll(menus);
            }
        }
        // 查询角色按钮
        List<Long> permissionIds = sysPermissionService.getPermissionIdByRoleId(id);
        if (CollectionUtil.isNotEmpty(permissionIds)) {
            QueryWrapper<SysPermission> queryWrapper = new QueryWrapper<>();
            queryWrapper.select("id, menu_id pid, name");
            queryWrapper.lambda().eq(SysPermission::getEnabled, GlobalConstant.ENABLED_YES)
                    .in(SysPermission::getId, permissionIds);
            List<Map<String, Object>> permissions = sysPermissionService.listMaps(queryWrapper);
            if (CollectionUtil.isNotEmpty(permissions)) {
                list.addAll(permissions);
            }
        }
        TreeNodeConfig config = new TreeNodeConfig();
        config.setParentIdKey("pid");
        config.setNameKey("name");
        config.setWeightKey("seq");
        List<Tree<Long>> tree = TreeUtil.build(list, 0L, config, (object, item) -> {
            item.putExtra("id", object.get("id"));
            item.putExtra("pid", object.get("pid"));
            item.putExtra("name", object.get("name"));
            item.putExtra("checked", 0);
        });
        result.setTree(tree);
        return result;
    }

    @Override
    public Boolean del(BaseParams params) {
        SysRole sysRole = super.getById(params.getId());
        if (sysRole == null) {
            throw new DataNotFoundException();
        }
        // 查询节点是否有用户
        LambdaQueryWrapper<SysUserRole> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SysUserRole::getRoleId, params.getId());
        Integer count = sysUserRoleService.count(wrapper);
        if (count > 0) {
            throw new BusinessException("角色下有用户，不能删除");
        }
        return super.removeById(params.getId());
    }

    @Override
    public Boolean enabled(BaseParams params) {
        SysRole sysRole = super.getById(params.getId());
        if (sysRole == null) {
            throw new DataNotFoundException();
        }
        return super.updateById(new SysRole() {{
            setId(params.getId());
            setEnabled(GlobalConstant.ENABLED_YES);
        }});
    }

    @Override
    public Boolean disabled(BaseParams params) {
        SysRole sysRole = super.getById(params.getId());
        if (sysRole == null) {
            throw new DataNotFoundException();
        }
        // 查询节点是否有用户
        LambdaQueryWrapper<SysUserRole> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SysUserRole::getRoleId, params.getId());
        Integer count = sysUserRoleService.count(wrapper);
        if (count > 0) {
            throw new BusinessException("角色下有用户，不能禁用");
        }
        return super.updateById(new SysRole() {{
            setId(params.getId());
            setEnabled(GlobalConstant.ENABLED_NO);
        }});
    }

    @Override
    public List<SysRoleResult> getListByOrgId(Long orgId) {
        LambdaQueryWrapper<SysRole> wrapper = new LambdaQueryWrapper();
        wrapper.eq(SysRole::getEnabled, GlobalConstant.ENABLED_YES);
        wrapper.eq(SysRole::getOrgId, orgId);
        List<SysRole> list = super.list(wrapper);
        return DozerConvertor.convertor(list, SysRoleResult.class);
    }

    @Override
    public Integer getCountByName(Long id, Long orgId, String name) {
        LambdaQueryWrapper<SysRole> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SysRole::getOrgId, orgId);
        wrapper.eq(SysRole::getName, name);
        // 编辑
        if (id != null) {
            wrapper.ne(SysRole::getId, id);
        }
        return super.count(wrapper);
    }

    @Override
    public List<Long> getRoleIdByUrlPermission(Long menuId, String urlPermission) {
        Set<Long> roleIds = new HashSet<>();
        // 菜单角色
        roleIds.addAll(sysMenuService.getRoleIdByUrlPermission(menuId, urlPermission));
        // 按钮角色
        roleIds.addAll(sysPermissionService.getRoleIdByUrlPermission(menuId, urlPermission));
        return ListUtil.toList(roleIds);
    }

    @Override
    public SysRolePermResult getPermByRoleId(Long roleId) {
        SysRolePermResult result = new SysRolePermResult();
        SysRole sysRole = super.getById(roleId);
        if (sysRole == null) {
            throw new DataNotFoundException();
        }
        List<Map<String, Object>> list = new ArrayList<>();
        // 查询全部菜单
        LambdaQueryWrapper<SysMenu> wrapper = new LambdaQueryWrapper<>();
        wrapper.select(SysMenu::getId, SysMenu::getPid, SysMenu::getName);
        wrapper.eq(SysMenu::getEnabled, GlobalConstant.ENABLED_YES);
        List<Map<String, Object>> menus = sysMenuService.listMaps(wrapper);
        if (CollectionUtil.isNotEmpty(menus)) {
            list.addAll(menus);
        }
        // 查询全部按钮
        QueryWrapper<SysPermission> queryWrapper = new QueryWrapper<>();
        queryWrapper.select("id, menu_id pid, name");
        queryWrapper.lambda().eq(SysPermission::getEnabled, GlobalConstant.ENABLED_YES);
        List<Map<String, Object>> permissions = sysPermissionService.listMaps(queryWrapper);
        if (CollectionUtil.isNotEmpty(permissions)) {
            list.addAll(permissions);
        }
        TreeNodeConfig config = new TreeNodeConfig();
        config.setParentIdKey("pid");
        config.setNameKey("name");
        config.setWeightKey("seq");
        List<Tree<Long>> tree = TreeUtil.build(list, 0L, config, (object, item) -> {
            item.putExtra("id", object.get("id"));
            item.putExtra("pid", object.get("pid"));
            item.putExtra("name", object.get("name"));
            item.putExtra("checked", 0);
        });
        result.setTree(tree);
        // 查询当前角色权限
        List<Long> ids = new ArrayList<>();
        List<Long> menuIds = sysMenuService.getMenuIdByRoleId(roleId);
        if (CollectionUtil.isNotEmpty(menuIds)) {
            ids.addAll(menuIds);
        }
        List<Long> permissionIds = sysPermissionService.getPermissionIdByRoleId(roleId);
        if (CollectionUtil.isNotEmpty(permissionIds)) {
            ids.addAll(permissionIds);
        }
        result.setIds(ids);
        return result;
    }

    @Override
    public Boolean modifyPerm(SysRolePermParams params) {
        SysRole sysRole = super.getById(params.getRoleId());
        if (sysRole == null) {
            throw new DataNotFoundException();
        }
        sysMenuService.modifyRoleMenu(params.getRoleId(), params.getIds());
        return sysPermissionService.modifyRolePermission(params.getRoleId(), params.getIds());
    }
}
